package fr.n7.sma.util;

import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.swing.event.EventListenerList;


public class FiniteSizeLinkedList<E> extends ConcurrentLinkedQueue<E> {
	
	private static final long serialVersionUID = -4341224626462906294L;
	
	private EventListenerList listeners;
	
	public static int DEFAULT_MAX_LENGTH = 100;
	private int maxLength;
	
	public FiniteSizeLinkedList() {
		this(DEFAULT_MAX_LENGTH);
	}

	public FiniteSizeLinkedList(Collection<E> c) {
		this(c, DEFAULT_MAX_LENGTH);
	}
	
	public FiniteSizeLinkedList(int maxLength) {
		super();
		this.maxLength = maxLength;
		listeners = new EventListenerList();
	}

	public FiniteSizeLinkedList(Collection<E> c, int maxLength) {
		super(c);
		reduce();
		this.maxLength = maxLength;
		listeners = new EventListenerList();
	}
	
	private void reduce(){
		while(size()>maxLength){
			E e = pollFirst();
			for(FiniteSizeListener<E> l : listeners.getListeners(FiniteSizeListener.class)){
				l.finiteSizeListReduced(e);
			}
		}
	}
	
	private E pollFirst() {
		return poll();
	}

	@Override
	public boolean add(E e){
		boolean r = super.add(e);
		reduce();
		return r;
	}
//
//	@Override
//	public void add(int index, E element){
//		super.add(index, element);
//		reduce();
//	}

	@Override
	public boolean addAll(Collection<? extends E> c){
		boolean r = super.addAll(c);
		reduce();
		return r;
	}

//	@Override
//	public  boolean addAll(int index, Collection<? extends E> c){
//		boolean r = super.addAll(index, c);
//		reduce();
//		return r;
//	}
//
//	@Override
//	public void addFirst(E e){
//		super.addFirst(e);
//		reduce();
//	}

	public void addLast(E e) {
		if(size()<maxLength){
			super.add(e);
		}
	}
	
	public void addListener(FiniteSizeListener<E> l){
		listeners.add(FiniteSizeListener.class, l);
	}
	
	public void removeListener(FiniteSizeListener<E> l){
		listeners.remove(FiniteSizeListener.class, l);
	}

	public int getMaxLength() {
		return maxLength;
	}

	public void setMaxLength(int maxLength) {
		this.maxLength = maxLength;
	}
}
